
#include "SocketMatTransmissionServer.h"
#include <sys/stat.h>
#include <unistd.h>
 
SocketMatTransmissionServer::SocketMatTransmissionServer(void)
{
}
 
 
SocketMatTransmissionServer::~SocketMatTransmissionServer(void)
{
}
 
 
int SocketMatTransmissionServer::socketConnect(int PORT, int flag)
{
	
	 if (flag == 0)
	 {
		server_sockfd = socket(AF_INET,SOCK_STREAM, 0); 
		server_sockaddr.sin_family = AF_INET;
		server_sockaddr.sin_port = htons(PORT);
		server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

		if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
		{
			perror("bind");
			return -1;
		}
	 
		if(listen(server_sockfd,5) == -1)
		{
			perror("listen");
			return -1;
		}
	 }
	
 
	struct sockaddr_in client_addr;
	socklen_t length = sizeof(client_addr);
 
	printf("server waiting...\n");
	sockConn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
	if(sockConn<0)
	{
		perror("connect");
		return -1;
	}
	else
	{
		printf("connect successful!\n");
		return 1;
	}
	
	close(server_sockfd);
}

int SocketMatTransmissionServer::socketAccept()
{

	struct sockaddr_in client_addr;
	socklen_t length = sizeof(client_addr);

   
 
	printf("\nserver waiting...\n");
	sockConn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
	if(sockConn<0)
	{
		perror("connect");
		return -1;
	}
	else
	{
		printf("connect successful!\n");		
		clientIp = inet_ntoa(client_addr.sin_addr);
		port = ntohs(client_addr.sin_port);
		printf("client ip：%s, port:%d\n", clientIp, port);
		sprintf(strDirectory, "/home/wj/log/%s/%d", clientIp, port);


		if((createMultiLevelDir(strDirectory)) != 0) {  
			printf("创建目录失败：%s\n",strDirectory); 
		}else{

			printf("创建目录成功：%s\n",strDirectory);
		}
		return 1;
	}
	
}

int SocketMatTransmissionServer::socketBind(int PORT)
{		 
	server_sockfd = socket(AF_INET,SOCK_STREAM, 0); 
	server_sockaddr.sin_family = AF_INET;
	server_sockaddr.sin_port = htons(PORT);
	server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
	{
		perror("bind");
		return -1;
	}
 
	if(listen(server_sockfd,5) == -1)
	{
		perror("listen");
		return -1;
	}	 
	
}
 
 
void SocketMatTransmissionServer::socketDisconnect(void)
{
	printf("%s:%d Disconnect!\n",clientIp, port);
	free(data.buf);
	close(sockConn);
}



int SocketMatTransmissionServer::send_res(int res)
{
	static long i =0,j =0 ;
	j = i/10;
	string label[] = {"SOLIDER","WARSHIP","VEHICLE","TANK","MISSILE","WARPLANE","RIFLE","SUBMARINE","CANNON"};

    Json::FastWriter writer;
    Json::Value ret;
    Json::Value rect;
    
    ret["label"] = label[res % 9];//label[j % 5];
    ret["probability"] = (rand()%254+1)/255.0;
	rect["x"] = 150 + rand()%100+1;
	rect["y"] = 159 + rand()%100+1;
	rect["w"] = 100;
	rect["h"] = 100;
	ret["rect"] = rect;

    string ret_str = writer.write(ret);
	int send_res = 0;
	send_res = send(sockConn,ret_str.c_str(),ret_str.length(),0) ;
	i++;
}

int SocketMatTransmissionServer::receive(struct infohead& head)
{
	int pos = 0;
	int len0 = 0;
	needRecv = sizeof(struct infohead);
	while (pos < needRecv)
	{
		len0 = recv(sockConn, (char*)(&head) + pos, needRecv - pos, 0);
		if (len0 <= 0)
		{
			return -1;
		}
		pos += len0;
		
	}

	data.buf = (char*)malloc(head.width*head.height*3/head.packageNum);
	return 0;

}

int SocketMatTransmissionServer::receive(cv::Mat& image)
{
	int returnflag = 0;
	cv::Mat img(height, width, CV_8UC3, cv::Scalar(0));
	needRecv = width*height*3/packageNum ;   // sizeof(data);
	count = 0;
	memset(data.buf,0,width*height*3/packageNum);
	for (int i = 0; i < packageNum; i++)
	{
		int pos = 0;
		int len0 = 0;
 
		while (pos < needRecv)
		{
			len0 = recv(sockConn, (char*)(data.buf) + pos, needRecv - pos, 0);
			//printf("len0 = %d\n", len0);
			if (len0 <= 0)
			{				
				return -1;
				break;
			}
			pos += len0;
			
		}
		len0 = recv(sockConn, (char*)(&data.flag), 4, 0);
		if (len0 !=4)
		{
			printf("receive flag error\n");
			return -1;
		}


		count = count + data.flag;
 
		int num1 = height / packageNum * i;
		for (int j = 0; j < height / packageNum; j++)
		{
			int num2 = j * width * 3;
			uchar* ucdata = img.ptr<uchar>(j + num1);
			for (int k = 0; k < width * 3; k++)
			{
				ucdata[k] = data.buf[num2 + k];
			}
		}
 
		if (data.flag == 2)
		{
			if (count == packageNum + 1)
			{
				image = img;
				returnflag = 1;
				count = 0;
			}
			else
			{
				count = 0;
				i = 0;
			}
		}
	}
	if(returnflag == 1)
		return 1;
	else
		return -1;
}



//创建多级目录
int SocketMatTransmissionServer::createMultiLevelDir(char* sPathName)  
{  
    char DirName[256];      
    int i, len;
    
    strcpy(DirName, sPathName);      
    len = strlen(DirName);             
    if('/' != DirName[len-1]) {  
        strcat(DirName, "/");
        len++;
    }           
          
    for(i=1; i<len; i++)      
    {      
        if('/' == DirName[i])      
        {      
            DirName[i] = '\0';      
            if(access(DirName, F_OK) != 0)      
            {      
                if(mkdir(DirName, 0777) == -1)      
                {       
                    perror("mkdir() failed!");       
                    return -1;       
                }      
            }    
            DirName[i] = '/';      
         }      
  }    
      
  return 0;      
}  


void SocketMatTransmissionServer::writeOpencvMat(cv::Mat& image)
{
	static int number =0;
	char  filePath[100];
	sprintf(filePath, "%s/%d.jpg", strDirectory, number++);
	imwrite(filePath,image);
}
